﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace RaProWorld
{
    class Ltan : RaProGame
    {

        ContentManager Content;
        Texture2D[] sprites;
        SoundEffect[] sounds;
        SoundEffectInstance soundEngineInstance;
        Ltan_bg background;
        Ltan_energyBar enregie;
        Ltan_player player;
        List<Ltan_item> items;
        List<Ltan_enemy> enemys;
        float itemSpawnRate;
        float enemySpawnRate;
        float itemCooldown;
        float enemyCooldown;
        Random rnd;
        SpriteFont testFont;
        KeyboardState keyboardState = Keyboard.GetState();
        Score scoreSet;
        public int score;


        public Ltan() 
        {

            Content = new ContentManager(Program.raProWorld.Services,"Content\\Games\\Ltan");
            
            sprites = new Texture2D[6];
            sounds = new SoundEffect[2];
            loadCon();
            background = new Ltan_bg(sprites);
            player = new Ltan_player(sprites[1],sounds[0]);
            items = new List<Ltan_item>();
            enemys = new List<Ltan_enemy>();
            rnd = new Random();
            enemySpawnRate = 200.0f;
            itemSpawnRate = 1250.0f;
            itemCooldown = (float)rnd.NextDouble() * itemSpawnRate + itemSpawnRate;
            enemyCooldown = (float)rnd.NextDouble() * enemySpawnRate + enemySpawnRate;
            enregie = new Ltan_energyBar(sprites[4],sprites[5]);
            scoreSet = Program.raProWorld.worldMap.objects[Program.raProWorld.worldMap.currentSelectedIndex].score;
            scoreSet.setScore(0);
            score = 0;
        }

        private void loadCon() 
        {
            sprites[0] = Content.Load<Texture2D>("bg-test");
            sprites[1] = Content.Load<Texture2D>("figur-test");
            sprites[2] = Content.Load<Texture2D>("gegner-test");
            sprites[3] = Content.Load<Texture2D>("item-test");
            sprites[4] = Content.Load<Texture2D>("energie-ramen-test");
            sprites[5] = Content.Load<Texture2D>("energie-balken-test");
            sounds[0]=Content.Load<SoundEffect>("boing");
            sounds[1] = Content.Load<SoundEffect>("Ltan-bgmusic");
            testFont = Content.Load<SpriteFont>("font1");
        }

        public void Update(GameTime gameTime) 
        {
            if (soundEngineInstance == null)
            {
                soundEngineInstance = sounds[1].Play(1.0f, 0.0f, 0.0f, true);
            }
            
            player.update(gameTime);
            handleInput();
            background.update(gameTime,player.scrolling,player.speed);
            for (int i = items.Count - 1; i >= 0; i--)
            {
                if (i >= items.Count) break;
                items[i].update(gameTime,player.scrolling,player.speed);
                
            }
            for (int i = enemys.Count - 1; i >= 0; i--)
            {
                if (i >= enemys.Count) break;
                enemys[i].update(gameTime, player.scrolling, player.speed,player.position);
                if (enemys[i].isRubbing&&(!enemys[i].isFalling)) 
                {
                    enregie.energie = (float)(enregie.energie - 0.1f);
                }

            }
            enregie.update(gameTime);
            if (enregie.energie <= 0) 
            {
                player.dead = true;
            }
            spawning();
            collision();
            kickOut();
            wackeln();
            if (player.scrolling) 
            {
                score += (int)player.speed;
            }
        }

        public void handleInput() 
        {
            keyboardState = Keyboard.GetState();
            player.handleInput();
            if (player.dead) 
            {
                if (keyboardState.IsKeyDown(Keys.R)) 
                {
                    reset();
                }
                if (keyboardState.IsKeyDown(Keys.Escape)) 
                {
                    if (score > scoreSet.getScore()) 
                    {
                        scoreSet.setScore(score);
                    }
                    reset();
                    Exit();
                }
            }
        }

        public void Draw(SpriteBatch spriteBatch,GameTime gameTime) 
        {
            background.draw(spriteBatch, gameTime);
            player.draw(spriteBatch,gameTime);
            for (int i = items.Count-1; i >= 0; i--) 
            {
                if (i >= items.Count) break;
                items[i].draw(spriteBatch, gameTime);
            }
            for (int i = enemys.Count - 1; i >= 0; i--)
            {
                if (i >= enemys.Count) break;
                enemys[i].draw(spriteBatch, gameTime);
            }
            enregie.draw(spriteBatch, gameTime);
            spriteBatch.DrawString(testFont, player.wackelRate.ToString(), new Vector2(30.0f, 30.0f), Color.Black);
            spriteBatch.DrawString(testFont, enregie.energie.ToString(), new Vector2(30.0f, 45.0f), Color.Black);
            spriteBatch.DrawString(testFont, "Score: "+score.ToString(), new Vector2(880.0f, 20.0f), Color.Black);
        }

        private void collision()
        {
            for (int i = items.Count - 1; i >= 0; i--)
            {
                if (i >= items.Count) break;
                if (player.hitbox.Intersects(items[i].hitbox)) 
                {
                    enregie.refill();
                    items.RemoveAt(i);
                }
            }
            for (int i = enemys.Count - 1; i >= 0; i--) 
            {
                if (i >= enemys.Count) break;
                if (player.hitbox.Intersects(enemys[i].hitbox)&&!enemys[i].isRubbing) 
                {
                    enemys[i].isRubbing = true;
                }
            }
        }

        private void kickOut() 
        {
            for (int i = items.Count - 1; i >= 0; i--)
            {
                if (i >= items.Count) break;
                if (items[i].position.X+(items[i].sprite.Width/2) <0 )
                {
                    items.RemoveAt(i);
                }
            }
            for (int i = enemys.Count - 1; i >= 0; i--)
            {
                if (i >= enemys.Count) break;
                if (enemys[i].position.X + (enemys[i].sprite.Width / 2) < 0)
                {
                    enemys.RemoveAt(i);
                }
                if (i >= enemys.Count) break;
                if (enemys[i].position.Y > 768 + (enemys[i].sprite.Height / 2)) 
                {
                    enemys.RemoveAt(i);
                }
            }
        }

        private void spawning() 
        {
            //itemspawning
            if (player.scrolling)
            {
                itemCooldown -= player.speed;
                enemyCooldown -= player.speed;
                if (itemCooldown <= 0.0f) 
                {
                    items.Add(new Ltan_item(sprites[3]));
                    itemCooldown = (float)rnd.NextDouble() * itemSpawnRate + itemSpawnRate;
                }
                if (enemyCooldown <= 0.0f) 
                {
                    enemys.Add(new Ltan_enemy(sprites[2],(float)rnd.NextDouble()*4.0f+1.0f));
                    enemyCooldown = (float)rnd.NextDouble() * enemySpawnRate + enemySpawnRate;
                }
            }
        }

        private void wackeln() 
        {
            for (int i = enemys.Count - 1; i >= 0; i--)
            {
                if (i >= enemys.Count) break;
                if ((player.wackelRate>=enemys[i].staerke)&&(enemys[i].isRubbing))
                {
                    enemys[i].isFalling = true;
                }
            }
        }

        private void reset() 
        {
            enemys = new List<Ltan_enemy>();
            items = new List<Ltan_item>();
            score = 0;
            enregie.reset();
            player.reset();
            background.reset();
        }

        #region RaProGame Members

        public void initialize()
        {
        }

        public void LoadContent(ContentManager Content)
        {
        }

        public void HandleInput()
        {
        }

        public void Exit()
        {
            Program.raProWorld.gameShell.runningGame = null;
            Program.raProWorld.GameState = "WORLDMAP";
            Program.raProWorld.worldMap.objects[Program.raProWorld.worldMap.currentSelectedIndex].score.setScore(scoreSet.getScore());
        }

        #endregion
    }
}
